﻿using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
using System.Windows.Forms;

namespace Borg.Framework
{
    public class SlotLabel : UserControl
    {
        private CheckBox _autoOpen;
        private CheckBox _autoPlug;
        private CheckBox _autoRegister;
        private CheckBox _autoRelease;

        private LinkLabel _close;

        private readonly Color _closed = Color.Red;

        private readonly IContainer components = null;

        private System.Windows.Forms.FlowLayoutPanel _flow1;
        private System.Windows.Forms.FlowLayoutPanel _flow2;

        private CheckBox _lazyLoad;
        private CheckBox _multiple;

        private bool _noUpdate;

        private LinkLabel _open;
        private readonly Color _opened = Color.Green;

        private Label _slot;
        private SlotInfo _slotInfo;
        private CheckBox _unique;

        public SlotLabel()
        {
            InitializeComponent();
            _slot.Font = new Font(Font, FontStyle.Bold);
        }

        public void Attach(SlotInfo slot)
        {
            _slotInfo = slot;

            Slot.PropertyChanged += PropertyChanged;
            Slot.Opened += Opened;
            Slot.Closed += Opened;

            _slot.Text = Slot.ToString();

            Opened(null, null);
            PropertyChanged(null, null);
        }

        private void autoOpen_CheckedChanged(object sender, EventArgs e)
        {
            if (!_noUpdate)
                Slot.AutoOpen = _autoOpen.Checked;
        }

        private void autoPlug_CheckedChanged(object sender, EventArgs e)
        {
            if (!_noUpdate)
                Slot.AutoPlug = _autoPlug.Checked;
        }

        private void autoRegister_CheckedChanged(object sender, EventArgs e)
        {
            if (!_noUpdate)
                Slot.AutoRegister = _autoRegister.Checked;
        }

        private void autoRelease_CheckedChanged(object sender, EventArgs e)
        {
            if (!_noUpdate)
                Slot.AutoRelease = _autoRelease.Checked;
        }

        private void close_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            var trace = new StackTrace(new StackFrame(true));
            Slot.Close();
        }

        public void Detach()
        {
            Slot.PropertyChanged -= PropertyChanged;
            Slot.Opened -= Opened;
            Slot.Closed -= Opened;
            
            _slotInfo = null;
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
                components.Dispose();

            base.Dispose(disposing);
        }

        private void InitializeComponent()
        {
            _flow1 = new System.Windows.Forms.FlowLayoutPanel();
            _slot = new Label();
            _open = new LinkLabel();
            _close = new LinkLabel();
            _flow2 = new System.Windows.Forms.FlowLayoutPanel();
            _autoOpen = new CheckBox();
            _autoRegister = new CheckBox();
            _autoPlug = new CheckBox();
            _autoRelease = new CheckBox();
            _lazyLoad = new CheckBox();
            _multiple = new CheckBox();
            _unique = new CheckBox();
            _flow1.SuspendLayout();
            _flow2.SuspendLayout();
            SuspendLayout();
            _flow1.AutoSize = true;
            _flow1.AutoSizeMode = AutoSizeMode.GrowAndShrink;
            _flow1.Controls.Add(_slot);
            _flow1.Controls.Add(_open);
            _flow1.Controls.Add(_close);
            _flow1.Dock = DockStyle.Top;
            _flow1.Location = new Point(0, 0);
            _flow1.Name = "_flow1";
            _flow1.Size = new Size(236, 18);
            _flow1.TabIndex = 0;
            _slot.AutoSize = true;
            _slot.Location = new Point(3, 0);
            _slot.Name = "_slot";
            _slot.Size = new Size(58, 18);
            _slot.TabIndex = 0;
            _slot.Text = "SlotInfo";
            _open.AutoSize = true;
            _open.Location = new Point(67, 0);
            _open.Name = "_open";
            _open.Size = new Size(43, 18);
            _open.TabIndex = 1;
            _open.TabStop = true;
            _open.Text = "Open";
            _open.LinkClicked += open_LinkClicked;
            _close.AutoSize = true;
            _close.Location = new Point(116, 0);
            _close.Name = "_close";
            _close.Size = new Size(42, 18);
            _close.TabIndex = 2;
            _close.TabStop = true;
            _close.Text = "Close";
            _close.LinkClicked += close_LinkClicked;
            _flow2.Controls.Add(_autoOpen);
            _flow2.Controls.Add(_autoRegister);
            _flow2.Controls.Add(_autoPlug);
            _flow2.Controls.Add(_autoRelease);
            _flow2.Controls.Add(_lazyLoad);
            _flow2.Controls.Add(_multiple);
            _flow2.Controls.Add(_unique);
            _flow2.Dock = DockStyle.Fill;
            _flow2.FlowDirection = FlowDirection.TopDown;
            _flow2.Location = new Point(0, 18);
            _flow2.Margin = new Padding(0);
            _flow2.Name = "_flow2";
            _flow2.Padding = new Padding(3, 0, 0, 0);
            _flow2.Size = new Size(236, 102);
            _flow2.TabIndex = 1;
            _autoOpen.AutoSize = true;
            _autoOpen.Location = new Point(6, 1);
            _autoOpen.Margin = new Padding(3, 1, 3, 1);
            _autoOpen.Name = "_autoOpen";
            _autoOpen.Size = new Size(0x5f, 0x16);
            _autoOpen.TabIndex = 3;
            _autoOpen.Text = "AutoOpen";
            _autoOpen.UseVisualStyleBackColor = true;
            _autoOpen.CheckedChanged += autoOpen_CheckedChanged;
            _autoRegister.AutoSize = true;
            _autoRegister.Location = new Point(6, 25);
            _autoRegister.Margin = new Padding(3, 1, 3, 1);
            _autoRegister.Name = "_autoRegister";
            _autoRegister.Size = new Size(112, 22);
            _autoRegister.TabIndex = 0;
            _autoRegister.Text = "AutoRegister";
            _autoRegister.UseVisualStyleBackColor = true;
            _autoRegister.CheckedChanged += autoRegister_CheckedChanged;
            _autoPlug.AutoSize = true;
            _autoPlug.Location = new Point(6, 49);
            _autoPlug.Margin = new Padding(3, 1, 3, 1);
            _autoPlug.Name = "_autoPlug";
            _autoPlug.Size = new Size(86, 22);
            _autoPlug.TabIndex = 1;
            _autoPlug.Text = "AutoPlug";
            _autoPlug.UseVisualStyleBackColor = true;
            _autoPlug.CheckedChanged += autoPlug_CheckedChanged;
            _autoRelease.AutoSize = true;
            _autoRelease.Location = new Point(6, 73);
            _autoRelease.Margin = new Padding(3, 1, 3, 1);
            _autoRelease.Name = "_autoRelease";
            _autoRelease.Size = new Size(110, 22);
            _autoRelease.TabIndex = 2;
            _autoRelease.Text = "AutoRelease";
            _autoRelease.UseVisualStyleBackColor = true;
            _autoRelease.CheckedChanged += autoRelease_CheckedChanged;
            _lazyLoad.AutoSize = true;
            _lazyLoad.Location = new Point(124, 1);
            _lazyLoad.Margin = new Padding(3, 1, 3, 1);
            _lazyLoad.Name = "_lazyLoad";
            _lazyLoad.Size = new Size(91, 22);
            _lazyLoad.TabIndex = 4;
            _lazyLoad.Text = "LazyLoad";
            _lazyLoad.UseVisualStyleBackColor = true;
            _lazyLoad.CheckedChanged += lazyLoad_CheckedChanged;
            _multiple.AutoSize = true;
            _multiple.Enabled = false;
            _multiple.Location = new Point(124, 25);
            _multiple.Margin = new Padding(3, 1, 3, 1);
            _multiple.Name = "_multiple";
            _multiple.Size = new Size(77, 22);
            _multiple.TabIndex = 5;
            _multiple.Text = "Multiple";
            _multiple.UseVisualStyleBackColor = true;
            _unique.AutoSize = true;
            _unique.Location = new Point(124, 49);
            _unique.Margin = new Padding(3, 1, 3, 1);
            _unique.Name = "_unique";
            _unique.Size = new Size(74, 22);
            _unique.TabIndex = 6;
            _unique.Text = "Unique";
            _unique.UseVisualStyleBackColor = true;
            _unique.CheckedChanged += unique_CheckedChanged;
            AutoScaleDimensions = new SizeF(8f, 18f);
            AutoScaleMode = AutoScaleMode.Font;
            Controls.Add(_flow2);
            Controls.Add(_flow1);
            Font = new Font("Tahoma", 9f, FontStyle.Regular, GraphicsUnit.Point, 0);
            Name = "SlotLabel";
            Size = new Size(236, 120);
            _flow1.ResumeLayout(false);
            _flow1.PerformLayout();
            _flow2.ResumeLayout(false);
            _flow2.PerformLayout();
            ResumeLayout(false);
            PerformLayout();
        }

        private void lazyLoad_CheckedChanged(object sender, EventArgs e)
        {
            if (!_noUpdate)
                Slot.LazyLoad = _lazyLoad.Checked;
        }

        private void open_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            Slot.Open();
        }

        private void Opened(object sender, SlotEventArgs agrs)
        {
            _slot.ForeColor = Slot.IsOpen
                ? _opened
                : _closed;

            _open.Enabled = !Slot.IsOpen;
            _close.Enabled = Slot.IsOpen;
        }

        private void PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            _noUpdate = true;
            _autoOpen.Checked = Slot.AutoOpen;
            _autoRegister.Checked = Slot.AutoRegister;
            _autoPlug.Checked = Slot.AutoPlug;
            _autoRelease.Checked = Slot.AutoRelease;
            _lazyLoad.Checked = Slot.LazyLoad;
            _multiple.Checked = Slot.SlotTypeInfo.Multiple;
            _multiple.Enabled = false;
            _unique.Checked = Slot.Unique;
            _noUpdate = false;
        }

        private void unique_CheckedChanged(object sender, EventArgs e)
        {
            if (!_noUpdate)
                Slot.Unique = _unique.Checked;
        }

        public SlotInfo Slot
        {
            get { return _slotInfo; 
            }
        }
    }
}

